#region Copyright(C) Pentia, 1997 - 2008. All rights reserved (R)

// *************************************************************************
// *                                                                       *
// * http://www.pentia.net/                                                *
// *                                                                       *
// * E-Mail: info@pentia.net                                                *
// *                                                                       *
// * Copyright(C) Pentia, 1997 - 2008. All rights reserved (R).            *
// *                                                                       *
// * LEGAL NOTICE: This is unpublished proprietary source code of Pentia.  *
// * The contents of this file are protected by copyright laws and         *
// * international copyright treaties, as well as other intellectual       *
// * property laws and treaties. These contents may not be extracted,      *
// * copied, modified or redistributed either as a whole or part thereof   *
// * in any form, and may not be used directly in, or to assist with, the  *
// * creation of derivative works of any nature without prior written      *
// * permission from Pentia. The above copyright notice does not           *
// * evidence any actual or intended publication of this file.             *
// *                                                                       *
// *************************************************************************

#endregion

#region using

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

#endregion

namespace CodeDom
{
  /// <summary>
  /// Represents an Item in Sitecore
  /// </summary>
  public class Item : IItem
  {
    private readonly SitecoreConnection _connection;
    private readonly Guid _id;
    private readonly string _name;
    private readonly Guid _parentId;
    private readonly Guid _templateID;
    private string _path;
    private Dictionary<Guid, Field> _fields = new Dictionary<Guid,Field>();
    private Template _template;
    private IEnumerable<Item> _children;

    internal Item(XmlElement element, SitecoreConnection connection)
    {
      _connection = connection;

      _id = new Guid(element.Attributes["id"].Value);
      _name = element.Attributes["name"].Value;
      _parentId = new Guid(element.Attributes["parentid"].Value);
      _templateID = new Guid(element.Attributes["tid"].Value);

      foreach (XmlElement fieldElement in element.SelectNodes("/data/data/item//version[1]/fields/field"))
      {
        Field field = new Field(fieldElement, Connection);
        _fields.Add(field.TemplateFieldID, field);
      }
    }

    public SitecoreConnection Connection
    {
      get { return _connection; }
    }

    #region IItem Members

    public Guid ParentId
    {
      get { return _parentId; }
    }

    public Item Parent
    {
      get
      {
        if (ParentId == Guid.Empty)
          return null;
        return Connection.GetItem(ParentId.ToString());
      }
    }

    public Guid ID
    {
      get { return _id; }
    }

    public String Name
    {
      get { return _name; }
    }

    public IEnumerable<Item> Children
    {
      get { 
        if (_children == null)
          _children = Connection.GetChildItems(ID.ToString()); 
        return _children;
      }
    }

    public Guid TemplateID
    {
      get { return _templateID; }
    }

    public Template Template
    {
      get { 
        if (_template == null)
          _template = Connection.GetTemplate(TemplateID);
        return _template; 
      }
    }

    /// <summary>
    /// Gets the fields on the item
    /// </summary>
    /// <value>The fields.</value>
    public IEnumerable<Field> Fields
    {
      get { return _fields.Values; }
    }

    /// <summary>
    /// Gets the value of a field by its ID
    /// </summary>
    /// <param name="id">The id.</param>
    /// <returns></returns>
    public Field GetField(Guid id)
    {
      return _fields.ContainsKey(id) ? _fields[id] : null;
    }

    /// <summary>
    /// Gets the value of a named field
    /// </summary>
    /// <param name="fieldName">Name of the field.</param>
    /// <returns></returns>
    public Field GetField(string fieldName)
    {
      return _fields.Values.Where(f=> String.Equals(f.Name, fieldName, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
    }

    public string Path
    {
      get
      {
        if (_path == null)
          _path = string.Format("{0}/{1}", Parent == null ? String.Empty : Parent.Path, Name);
        return _path;
      }
    }

    #endregion
  }
}